"""
Seaborn 折线图（Lineplot）基础示例

知识点：
1. 基本折线图绘制
2. 使用 hue 绘制多条线
3. 置信区间的显示和控制
4. 使用 style 和 markers 定制线条样式
5. 数据聚合和估计器的使用
"""

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np

# 先设置 seaborn 主题
sns.set_theme(style="darkgrid")

# 然后强制设置中文字体（必须在 set_theme 之后）
plt.rcParams['font.sans-serif'] = ['PingFang HK', 'Hiragino Sans GB', 'STHeiti', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
plt.rcParams['font.family'] = 'sans-serif'

# 创建时间序列数据
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=365, freq='D')

# 模拟三个产品的销售数据
products = ['产品A', '产品B', '产品C']
data_list = []

for product in products:
    base = np.random.randint(100, 200)
    trend = np.linspace(0, 50, 365)
    seasonal = 30 * np.sin(np.linspace(0, 4*np.pi, 365))
    noise = np.random.normal(0, 10, 365)
    sales = base + trend + seasonal + noise
    
    for i, date in enumerate(dates):
        data_list.append({
            '日期': date,
            '销售额': sales[i],
            '产品': product,
            '月份': date.month,
            '季度': f'Q{(date.month-1)//3 + 1}'
        })

df = pd.DataFrame(data_list)

# 创建多子图
fig, axes = plt.subplots(2, 3, figsize=(18, 12))
fig.suptitle('Seaborn 折线图基础示例', fontsize=16, fontweight='bold')

# 1. 基础折线图
product_a = df[df['产品'] == '产品A']
sns.lineplot(
    data=product_a,
    x='日期',
    y='销售额',
    ax=axes[0, 0]
)
axes[0, 0].set_title('1. 基础折线图（单产品）')
axes[0, 0].tick_params(axis='x', rotation=45)

# 2. 使用 hue 绘制多条线
sns.lineplot(
    data=df,
    x='日期',
    y='销售额',
    hue='产品',
    ax=axes[0, 1]
)
axes[0, 1].set_title('2. 使用 hue 绘制多产品对比')
axes[0, 1].tick_params(axis='x', rotation=45)

# 3. 关闭置信区间
sns.lineplot(
    data=df,
    x='日期',
    y='销售额',
    hue='产品',
    ci=None,  # 不显示置信区间
    ax=axes[0, 2]
)
axes[0, 2].set_title('3. 关闭置信区间 (ci=None)')
axes[0, 2].tick_params(axis='x', rotation=45)

# 4. 使用 markers 添加数据点标记（采样显示）
monthly_data = df.groupby(['产品', pd.Grouper(key='日期', freq='M')]).agg({
    '销售额': 'mean'
}).reset_index()

sns.lineplot(
    data=monthly_data,
    x='日期',
    y='销售额',
    hue='产品',
    markers=True,
    marker='o',
    markersize=8,
    ax=axes[1, 0]
)
axes[1, 0].set_title('4. 添加数据点标记（月度数据）')
axes[1, 0].tick_params(axis='x', rotation=45)

# 5. 使用 style 区分线型
sns.lineplot(
    data=monthly_data,
    x='日期',
    y='销售额',
    hue='产品',
    style='产品',
    markers=True,
    dashes=False,  # 使用实线
    ax=axes[1, 1]
)
axes[1, 1].set_title('5. 使用 style 定制线型')
axes[1, 1].tick_params(axis='x', rotation=45)

# 6. 自定义估计器和置信区间
# 按月份聚合，显示标准差
sns.lineplot(
    data=df,
    x='月份',
    y='销售额',
    hue='产品',
    estimator='mean',  # 使用均值聚合
    ci='sd',  # 显示标准差而非置信区间
    markers=True,
    marker='o',
    markersize=10,
    linewidth=2.5,
    ax=axes[1, 2]
)
axes[1, 2].set_title('6. 按月聚合 + 标准差区间')
axes[1, 2].set_xlabel('月份')
axes[1, 2].set_xticks(range(1, 13))

plt.tight_layout()
plt.savefig('/Users/binming/Desktop/CodeBase/python/Python语法/1-常用库/1-数据分析/Seaborn关系图示例/2-lineplot_基础.png', 
            dpi=300, bbox_inches='tight')
plt.show()

print("=" * 60)
print("折线图核心参数说明：")
print("=" * 60)
print("x, y        : 指定x轴和y轴的数据列")
print("hue         : 用颜色区分不同系列")
print("style       : 用线型区分不同系列")
print("markers     : 是否显示数据点标记")
print("dashes      : 是否使用虚线")
print("ci          : 置信区间 (95, 'sd', None)")
print("estimator   : 聚合函数 ('mean', 'median', 'sum' 等)")
print("linewidth   : 线条宽度")
print("markersize  : 标记点大小")
print("=" * 60)
print(f"\n数据集大小: {len(df)} 行")
print(f"日期范围: {df['日期'].min()} 到 {df['日期'].max()}")
